import React from 'react';

import PropTypes from 'prop-types';
import Utils from '../common/Utils';
import Const from '../common/const';
import TileMap from '../plugins/TileMap/TileMap';

export default class TileMapCanvas extends React.Component {

    static propTypes = {
        config: PropTypes.object,
        tileMap: PropTypes.func,
        onChange: PropTypes.func
    }

    cachedConfig;

    state = {
        dirty: true,
        canvasWidth: Const.TileWidth * Const.PaletteTileCountPerLine,
        canvasHeight: Const.TileWidth * Const.PaletteTileCountPerLine
    }

    render() {
        let props = { ...this.props };
        delete props.config;
        delete props.tileMap;
        this.init().done();
        return <canvas
            width={this.state.canvasWidth}
            height={this.state.canvasHeight}
            ref={canvas => this.canvas = canvas}
            onClick={this.onClick.bind(this)}
            {...props} />;
    }

    componentDidMount() {
        this.canvasContext = this.canvas.getContext('2d');
        this.init().done();
    }

    async init() {
        if (this.state.dirty === true) {
            this.state.dirty = 'sweeping';
            let config = await Utils.flattenValue(this.props.config);
            if (this.tileMap == null) {
                this.tileMap = new (this.props.tileMap || TileMap)(this.canvasContext);
            } 
            await this.tileMap.setConfig(config);
            //Utils.log('init', this.tileMap.config);
            this.setState({ 
                dirty: false,
                canvasWidth: this.tileMap.config.width * this.tileMap.config.tileWidth,
                canvasHeight: this.tileMap.config.height * this.tileMap.config.tileHeight
            });
            this.draw();
            if (this.props.onChange) {
                this.props.onChange(this);
            }
        }
    }

    draw() {
        if (this.tileMap) {
            this.tileMap.draw();
        }
    }

    shouldComponentUpdate(nextProps, nextState) {
        //console.log('shouldComponentUpdate', nextProps);
        //let result = super.shouldComponentUpdate(nextProps, nextState, nextContext);
        if (Utils.deepEquals(this.cachedConfig, nextProps.config) && 
            Utils.deepEquals(this.state, nextState, { exclude: ['dirty'] })) {
            return false;
        }
        this.cachedConfig = Utils.deepCopy(nextProps.config);
        nextState.dirty = true;
        
        return true;
    }

    onClick(e) {
        let x = e.nativeEvent.offsetX;
        let y = e.nativeEvent.offsetY;
        this.tileMap.onClick({ x, y });
        if (this.props.onChange) {
            this.props.onChange(this);
        }
    }
}